<?php
namespace App\Services\Factory\Payment;

use AlipayFundTransToaccountTransferRequest;
use AlipayNotify;
use AlipaySubmit;
use AlipayTradeRefundRequest;
use AopClient;
use App\Models\AlipayLog;
use App\Services\Factory\PaymentFactory;
use App\Services\IWeixinService;
use CLogFileHandler;
use JsApiPay;
use Log;
use PayNotifyCallBack;
use WxPayApi;
use WxPayLog;
use WxPayUnifiedOrder;

/**
 * 支付宝支付
 * Class WxPay
 */
class AliPay extends PaymentFactory
{

    private $client;

    /**
     * WxPay constructor.
     */
    public function __construct()
    {
        defined('ALIPAY_APP_ID') or define('ALIPAY_APP_ID',config('services.AlipayAppID'));
        defined('ALIPAY_RSA_PRIVATE_KEY') or define('ALIPAY_RSA_PRIVATE_KEY',config('services.AlipayRsaPrivateKey'));
        defined('ALIPAY_RSA_PUBLIC_KEY') or define('ALIPAY_RSA_PUBLIC_KEY',config('services.AlipayRsaPublicKey'));

        require_once(app_path('Libs/AlipaySdk/AopSdk.php'));

        $aop = new AopClient;
        $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
        $aop->appId = ALIPAY_APP_ID;
        $aop->rsaPrivateKey = ALIPAY_RSA_PRIVATE_KEY;
        $aop->debugInfo=true;
        $aop->format = "json";
        $aop->charset = "UTF-8";
        $aop->signType = "RSA2";
        $aop->alipayrsaPublicKey = ALIPAY_RSA_PUBLIC_KEY;

        $this->client = &$aop;
    }

    public function verifyReturn(){
        defined('ALIPAY_PARTNER') or define('ALIPAY_PARTNER',config('services.AlipayPartner'));
        defined('ALIPAY_PARTNER_PRIVATE_KEY') or define('ALIPAY_PARTNER_PRIVATE_KEY',config('services.AlipayPartnerPrivateKey'));
        defined('ALIPAY_PARTNER_PUBLIC_KEY') or define('ALIPAY_PARTNER_PUBLIC_KEY',config('services.AlipayPartnerPublicKey'));

        require_once(app_path('Libs/AlipayMapiSdk/alipay.config.php'));
        require_once(app_path('Libs/AlipayMapiSdk/lib/alipay_notify.class.php'));

        $alipayNotify = new AlipayNotify($alipay_config);
        $verify_result = $alipayNotify->verifyReturn();

        if($verify_result) {//验证成功

            //商户订单号
            $out_trade_no = $_GET['out_trade_no'];

            //支付宝交易号
            $trade_no = $_GET['trade_no'];

            if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') {
                return $out_trade_no;
            }
        }
        return false;
    }

    public function form($order_number, $amount, $description,array $attach)
    {
        defined('ALIPAY_PARTNER') or define('ALIPAY_PARTNER',config('services.AlipayPartner'));
        defined('ALIPAY_PARTNER_PRIVATE_KEY') or define('ALIPAY_PARTNER_PRIVATE_KEY',config('services.AlipayPartnerPrivateKey'));
        defined('ALIPAY_PARTNER_PUBLIC_KEY') or define('ALIPAY_PARTNER_PUBLIC_KEY',config('services.AlipayPartnerPublicKey'));

        require_once(app_path('Libs/AlipayMapiSdk/alipay.config.php'));
        require_once(app_path('Libs/AlipayMapiSdk/lib/alipay_submit.class.php'));

        //构造要请求的参数数组，无需改动
        $parameter = array(
            "service"       => $alipay_config['service'],
            "partner"       => $alipay_config['partner'],
            "seller_id"  => $alipay_config['seller_id'],
            "payment_type"	=> $alipay_config['payment_type'],
            "notify_url"	=> url('callback/alipay'),
            "return_url"	=> array_get($attach,'return_url',url()->current()),

            "anti_phishing_key"=>$alipay_config['anti_phishing_key'],
            "exter_invoke_ip"=>$alipay_config['exter_invoke_ip'],
            "out_trade_no"	=> $order_number,
            "subject"	=> $description,
            "total_fee"	=> $amount,
            "body"	=> $description,
            "_input_charset"	=> trim(strtolower($alipay_config['input_charset']))
            //其他业务参数根据在线开发文档，添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.kiX33I&treeId=62&articleId=103740&docType=1
            //如"参数名"=>"参数值"

        );

        //建立请求
        $alipaySubmit = new AlipaySubmit($alipay_config);
        $html_text = $alipaySubmit->buildRequestForm($parameter,"get", "确认");
        return $html_text;
    }

    public function transfer($trade_number, $payee_real_name, $payee_account, $amount, $description)
    {
        $request = new AlipayFundTransToaccountTransferRequest();
        $bizContent = [
            "out_biz_no" => $trade_number,
            "payee_type" => "ALIPAY_LOGONID",
            "payee_account" => $payee_account,
            "amount" => $amount,
            "payer_show_name" => $description,
            "payee_real_name" => $payee_real_name,
            "remark" => $description,//转账备注
        ];
        $request->setBizContent(json_encode($bizContent));
        $response = $this->client->execute($request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $response->$responseNode->code;
        if(!empty($resultCode)&&$resultCode == 10000){
            $this->log('转账成功: '.json_encode($bizContent));
            return $response->$responseNode->order_id;
        }else{
            $this->log('转账失败: '.json_encode($bizContent).': '.json_encode($response->$responseNode));
            return false;
        }
    }

    public function refund($trade_number, $pay_trade_number, $transaction_id, $amount)
    {
        $request = new AlipayTradeRefundRequest ();
        $bizContent = [
            "out_trade_no"=>$pay_trade_number,
            "trade_no"=>$transaction_id,
            "refund_amount"=>$amount,
            "refund_reason"=>config('app.name')."订单退款",//退款的原因说明
            "out_request_no"=>$trade_number,
            "operator_id"=>"OP001",//商户的操作员编号
            "store_id"=>"NJ_S_001",//商户的门店编号
            "terminal_id"=>"NJ_T_001",//商户的终端编号
        ];
        $request->setBizContent(json_encode($bizContent));
        $response = $this->client->execute($request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $response->$responseNode->code;
        if(!empty($resultCode)&&$resultCode == 10000){
            $this->log('退款成功: '.json_encode($bizContent));
            return true;
        }else{
            $this->log('退款失败: '.json_encode($bizContent).': '.json_encode($response->$responseNode));
            return false;
        }
    }

    public function notify()
    {
        defined('ALIPAY_PARTNER') or define('ALIPAY_PARTNER',config('services.AlipayPartner'));
        defined('ALIPAY_PARTNER_PRIVATE_KEY') or define('ALIPAY_PARTNER_PRIVATE_KEY',config('services.AlipayPartnerPrivateKey'));
        defined('ALIPAY_PARTNER_PUBLIC_KEY') or define('ALIPAY_PARTNER_PUBLIC_KEY',config('services.AlipayPartnerPublicKey'));

        require_once(app_path('Libs/AlipayMapiSdk/alipay.config.php'));
        require_once(app_path('Libs/AlipayMapiSdk/lib/alipay_notify.class.php'));

        $alipayNotify = new AlipayNotify($alipay_config);
        $verify_result = $alipayNotify->verifyNotify();

        if($verify_result) {//验证成功

            //商户订单号
            $out_trade_no = $_POST['out_trade_no'];

            //支付宝交易号
            $trade_no = $_POST['trade_no'];

            //交易状态
            $trade_status = $_POST['trade_status'];

            if($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {
                return [$out_trade_no,$trade_no,[]];
            }
        }
        return [null,null,null];
    }

    public function log($message)
    {
        return AlipayLog::create(['content'=>$message]);
//        Log::debug('Alipay log: '.$message);
    }

}